package com.cloud.xtools.common.interceptor;

import com.cloud.xtools.common.annotation.Auth;
import com.cloud.xtools.common.annotation.DisAuth;
import com.cloud.xtools.common.exception.AuthenticationException;
import com.cloud.xtools.common.exception.ServiceException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Parameter;
import java.util.*;

/**
 * @author Daixinguo
 */
@Component
public class RequestAuthorizationInterceptor implements HandlerInterceptor {

    // 请求前执行
    // 返回 true 继续处理请求，返回 false 表示请求被拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // System.out.println("RequestAuthorizationInterceptor");

        if (handler instanceof HandlerMethod handlerMethod) {

            // 获取控制器类名
            // String controllerName = handlerMethod.getBeanType().getSimpleName();
            // System.out.println("Controller: " + controllerName);

            // 获取方法名
            // String methodName = handlerMethod.getMethod().getName();
            // System.out.println("Method: " + methodName);

            // 已登录用户的信息
            Object username = request.getAttribute("username");

            if (username != null) {
                com.cloud.xtools.common.util.Auth.setRequest(request);
            }

            final var disAuthTypeAnnotation = handlerMethod.getBeanType().getAnnotation(DisAuth.class);
            // System.out.println(disAuthTypeAnnotation);
            if (disAuthTypeAnnotation != null){

                // 控制器类上注解了 @DisAuth，但是方法上存在 @Auth 注解，则需要进行登录验证
                // @Auth 只支持方法上注解，与类上的 @DisAuth 配合使用
                final var disAuthFuncAnnotation = handlerMethod.getMethod().getAnnotation(Auth.class);
                if (disAuthFuncAnnotation != null && username == null){
                    throw new AuthenticationException("您尚未登录或登录状态已过期，请重新登录！");
                }

                return true;
            }

            final var disAuthFuncAnnotation = handlerMethod.getMethod().getAnnotation(DisAuth.class);
            if (disAuthFuncAnnotation != null){
                return true;
            }

            if (username == null) {
                throw new AuthenticationException("您尚未登录或登录状态已过期，请重新登录！");
            }
        }


        return true;
    }

    // 请求后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        // 处理完请求后，视图渲染之前执行
        // System.out.println("[postHandle] Response Status: " + response.getStatus());
    }

    // 完成请求处理后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        // 清理工作，比如释放资源等
        // System.out.println("[afterCompletion] Request Completed!");
    }
}
